package com.gzx.plugin.website.protocol.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.gzx.plugin.website.access.service.GzxAccessLogService;
import com.gzx.plugin.website.configs.entity.GzxWebsiteConfig;
import com.gzx.plugin.website.configs.service.GzxWebsiteConfigService;
import com.gzx.plugin.website.protocol.bo.*;
import com.gzx.plugin.website.protocol.entity.GzxMediationProtocol;
import com.gzx.plugin.website.protocol.mapper.GzxMediationProtocolMapper;
import com.gzx.plugin.website.protocol.service.GzxMediationProtocolSaveDbService;
import com.gzx.plugin.website.protocol.service.GzxMediationProtocolService;
import com.gzx.plugin.website.protocol.vo.GzxMediationProtocolOutVo;
import com.gzx.plugin.website.protocol.vo.GzxMediationProtocolVo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.consts.IntConstant;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.mvc.service.impl.BaseServiceImpl;
import vip.xiaonuo.common.pojo.CommonResult;
import vip.xiaonuo.common.util.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zjt
 * @description
 * @date 2025/4/15 15:54
 */
@Slf4j
@Service
@DS("website")
public class GzxMediationProtocolServiceImpl extends BaseServiceImpl<GzxMediationProtocolAddOrEditBo, GzxMediationProtocolVo, GzxMediationProtocolQueryBo, GzxMediationProtocolMapper, GzxMediationProtocol> implements GzxMediationProtocolService {

    private final GzxMediationProtocolSaveDbService mediationProtocolSaveDbService;

    private final GzxAccessLogService accessLogService;

    private final CommonCacheOperator cacheOperator;

    private final GzxWebsiteConfigService websiteConfigService;

    public GzxMediationProtocolServiceImpl(GzxMediationProtocolMapper baseMapper, GzxMediationProtocolSaveDbService mediationProtocolSaveDbService, GzxAccessLogService accessLogService, CommonCacheOperator cacheOperator, GzxWebsiteConfigService websiteConfigService) {
        super(baseMapper);
        this.mediationProtocolSaveDbService = mediationProtocolSaveDbService;
        this.accessLogService = accessLogService;
        this.cacheOperator = cacheOperator;
        this.websiteConfigService = websiteConfigService;
    }

    private static final String PROTOCOL_CONTENT = "受理案由：被告/申请人：debtorName通过platform(product)借款loanAmount元，并签署具有法律效益的借贷协议，截至caseDate，被告/被申请人未按合同约定履行合同义务，根据原告/申请方所提交的资料.并依据《中华人民共和国调解法》、《最高人民法院关于人民法院进一步深化多元化纠纷解决机制改革的意见》等规定依法通知双方当事人进行诉前调解工作，双方可登陆companyName官网：officialWebsite及官方认证的“weChatOfficialAccount”的微信服务号中进行案件查询并积极进行诉前调解工作。";

    @Override
    protected LambdaQueryWrapper<GzxMediationProtocol> buildQueryWrapper(GzxMediationProtocolQueryBo queryBo) {
        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
        return Wrappers.<GzxMediationProtocol>lambdaQuery()
                .eq(queryBo.getConfigId() != null, GzxMediationProtocol::getConfigId, queryBo.getConfigId())
                //唯度
                .eq("1944637731787374594".equals(loginUser.getOrgId()), GzxMediationProtocol::getCreateUser, loginUser.getId())
                .eq(StringUtils.isNotBlank(queryBo.getDebtorName()), GzxMediationProtocol::getDebtorName, queryBo.getDebtorName())
                .eq(StringUtils.isNotBlank(queryBo.getDebtorCardId()), GzxMediationProtocol::getDebtorCardId, CommonCryptogramUtil.doSm1AesEncrypt(queryBo.getDebtorCardId()))
                .eq(StringUtils.isNotBlank(queryBo.getMediatorName()), GzxMediationProtocol::getMediatorName, queryBo.getMediatorName())
                .between(StringUtils.isNotBlank(queryBo.getBeginTime()) && StringUtils.isNotBlank(queryBo.getEndTime()), GzxMediationProtocol::getCreateTime, queryBo.getBeginTime(), queryBo.getEndTime())
                .orderByDesc(GzxMediationProtocol::getId);
    }

    /**
     * 调解协议导入
     *
     * @param mediationProtocolImportAddBo
     * @param multipartFile
     */
    @Override
    public void importExcel(GzxMediationProtocolImportAddBo mediationProtocolImportAddBo, MultipartFile multipartFile) {
        List<GzxMediationProtocolExcelBo> protocolExcelBoList = CommonExcelUtil.importExcel(multipartFile, GzxMediationProtocolExcelBo.class);
        List<GzxMediationProtocol> protocolList = MapstructUtils.convert(protocolExcelBoList, GzxMediationProtocol.class);
        if (CollectionUtil.isNotEmpty(protocolList)) {
            completionInfo(protocolList, mediationProtocolImportAddBo);
            insertBatch(protocolList);
        }
    }

    /**
     * 预览调解协议
     *
     * @param id
     * @return
     */
    @Override
    public GzxMediationProtocolOutVo preview(Long id) {
        GzxMediationProtocol protocol = baseMapper.selectById(id);
        GzxMediationProtocolOutVo mediationProtocolOutVo = new GzxMediationProtocolOutVo();
        BeanUtils.copyProperties(protocol, mediationProtocolOutVo);
        return mediationProtocolOutVo;
    }

    /**
     * 根据身份证号获取调解函数据
     *
     * @param mediationProtocolOutQueryBo
     * @param request
     * @return
     */
    @Override
    public CommonResult<List<GzxMediationProtocolOutVo>> selectListByDebtorCardId(GzxMediationProtocolOutQueryBo mediationProtocolOutQueryBo, HttpServletRequest request) {
        String phone = mediationProtocolOutQueryBo.getDgfd();
        String debtorCardId = mediationProtocolOutQueryBo.getFvd();
        if (!verifyToken(request, phone, debtorCardId)) {
            return CommonResult.error(401, "身份信息校验失败");
        }
        GzxWebsiteConfig websiteConfig = websiteConfigService.getConfigIdByHost(mediationProtocolOutQueryBo.getHost());
        if (websiteConfig == null) {
            return CommonResult.data(List.of());
        }
        List<GzxMediationProtocol> protocolList = baseMapper.selectList(Wrappers.<GzxMediationProtocol>lambdaQuery()
                .eq(GzxMediationProtocol::getConfigId, websiteConfig.getId())
                .eq(GzxMediationProtocol::getDebtorCardId, CommonCryptogramUtil.doSm1AesEncrypt(debtorCardId)));
        List<GzxMediationProtocolOutVo> outVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(protocolList)) {
            accessLogService.add(CommonIpAddressUtil.getIp(request), websiteConfig.getId(), phone, debtorCardId);
            for (GzxMediationProtocol mediationProtocol : protocolList) {
                GzxMediationProtocolOutVo mediationProtocolOutVo = new GzxMediationProtocolOutVo();
                BeanUtils.copyProperties(mediationProtocol, mediationProtocolOutVo);
                outVoList.add(mediationProtocolOutVo);
            }
        }
        return CommonResult.data(outVoList);
    }

    /**
     * API调用生成调解函
     *
     * @param mediationProtocolExcelBoList
     * @param request
     */
    @Override
    public void apiGenerateProtocol(List<GzxMediationProtocolExcelBo> mediationProtocolExcelBoList, HttpServletRequest request) {
        List<GzxMediationProtocol> protocolList = MapstructUtils.convert(mediationProtocolExcelBoList, GzxMediationProtocol.class);
        if (CollectionUtil.isNotEmpty(protocolList)) {
            GzxMediationProtocolImportAddBo mediationProtocolImportAddBo = new GzxMediationProtocolImportAddBo();
            GzxWebsiteConfig websiteConfig = websiteConfigService.getConfigIdByHost("www.tjjrtj.com");
            BeanUtils.copyProperties(websiteConfig, mediationProtocolImportAddBo);
            mediationProtocolImportAddBo.setExpiryDate(CommonDateUtil.getCurrentMonthLastDay());
            mediationProtocolImportAddBo.setConfigId(websiteConfig.getId());
            completionInfo(protocolList, mediationProtocolImportAddBo);
            insertBatch(protocolList);
        }
    }

    private void insertBatch(List<GzxMediationProtocol> protocolList) {
        List<List<GzxMediationProtocol>> batchList = Lists.partition(protocolList, IntConstant.VALUE_10000);
        long startTime = System.currentTimeMillis();
        batchList.forEach(mediationProtocolSaveDbService::insertBatch);
        log.info("处理完成，共{}条数据，总耗时: {}", batchList.size(), System.currentTimeMillis() - startTime);
    }

    private void completionInfo(List<GzxMediationProtocol> protocolList, GzxMediationProtocolImportAddBo mediationProtocolImportAddBo) {
        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
        //从redis获取原子key
        long initValue = cacheOperator.getIncrAtomic("protocol:doc:num", CommonDateUtil.getYearRemainingSeconds()).intValue();
        for (int i = 0; i < protocolList.size(); i++) {
            GzxMediationProtocol protocol = protocolList.get(i);
            protocol.setCompanyName(mediationProtocolImportAddBo.getCompanyName());
            protocol.setProvAbbr(mediationProtocolImportAddBo.getProvAbbr());
            protocol.setOfficialWebsite(mediationProtocolImportAddBo.getOfficialWebsite());
            protocol.setWeChatOfficialAccount(mediationProtocolImportAddBo.getWeChatOfficialAccount());
            protocol.setOfficialSealUrl(mediationProtocolImportAddBo.getOfficialSealUrl());
            protocol.setTenantId(loginUser.getTenantId());
            protocol.setCreateUser(loginUser.getId());
            protocol.setContent(completionContent(protocol));
            protocol.setExpiryDate(mediationProtocolImportAddBo.getExpiryDate());
            protocol.setConfigId(mediationProtocolImportAddBo.getConfigId());
            // 分配唯一文档编号
            protocol.setDocumentNumber((int) (initValue + i));
        }
        // 处理完成后更新Redis中的值
        cacheOperator.setIncrAtomic("protocol:doc:num", (int) (initValue + protocolList.size()));
    }

    private String completionContent(GzxMediationProtocol protocol) {
        String content = PROTOCOL_CONTENT;
        content = content.replace("debtorName", StringUtils.isNoneBlank(protocol.getDebtorName()) ? protocol.getDebtorName() : "");
        content = content.replace("platform", StringUtils.isNoneBlank(protocol.getPlatform()) ? protocol.getPlatform() : "");
        content = content.replace("product", StringUtils.isNoneBlank(protocol.getProduct()) ? protocol.getProduct() : "");
        content = content.replace("loanAmount", protocol.getLoanAmount() != null ? protocol.getLoanAmount().toString() : "");
        content = content.replace("caseDate", StringUtils.isNoneBlank(protocol.getCaseDate()) ? protocol.getCaseDate() : "");
        content = content.replace("companyName", StringUtils.isNoneBlank(protocol.getCompanyName()) ? protocol.getCompanyName() : "");
        content = content.replace("officialWebsite", StringUtils.isNoneBlank(protocol.getOfficialWebsite()) ? protocol.getOfficialWebsite() : "");
        content = content.replace("weChatOfficialAccount", StringUtils.isNoneBlank(protocol.getWeChatOfficialAccount()) ? protocol.getWeChatOfficialAccount() : "");
        return content;
    }

    public boolean verifyToken(HttpServletRequest httpServletRequest, String phone, String debtorCardId) {
        String headerToken = httpServletRequest.getHeader("Website-Token");
        if (StringUtils.isBlank(headerToken)) {
            throw new CommonException("Token过期");
        }
        String uuid = cacheOperator.getCatchString(headerToken);
        if (StringUtils.isBlank(uuid)) {
            return false;
        }
        String token = CommonCryptogramUtil.doMd5(phone + debtorCardId + CommonIpAddressUtil.getIp(httpServletRequest) + uuid);
        return headerToken.equals(token);
    }
}
